package cn.mini.mybatis.mybatis.mapping;


import cn.mini.mybatis.mybatis.session.Configuration;

/**
 * MapperStatement 用于保存 SQL 相关信息。
 * 该类封装了与 SQL 语句执行相关的配置、唯一标识、SQL 类型以及绑定的 SQL 信息等。
 */
public class MappedStatement {
    /**
     * MyBatis 的配置对象，包含了全局的配置信息，用于指导 SQL 语句的执行。
     */
    private Configuration configuration;

    /**
     * SQL 语句的唯一标识，通常为 "命名空间.id" 的形式
     * 用于在配置中唯一确定一条 SQL 语句，方便后续的查找和执行。
     */
    private String id;

    /**
     * SQL 语句的类型，如 SELECT、INSERT、UPDATE、DELETE
     * 用于区分不同类型的 SQL 操作，以便执行不同的处理逻辑。
     */
    private SqlCommandType sqlCommandType;
    /**
     * SQL 语句绑定信息
     * 包含最终要执行的 SQL 语句、参数映射等相关信息。
     */
    private SqlSource sqlSource;
    /**
     * 结果类型
     */
     Class<?> resultType;

    /**
     * 私有构造函数，防止外部直接实例化 MappedStatement 对象，
     * 确保只能通过 Builder 模式来创建对象。
     */
    MappedStatement() {
        // constructor disabled
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    /**
     * 内部静态类，用于构建 MappedStatement 对象，采用建造者模式。
     * 该模式允许分步设置 MappedStatement 对象的属性，最后统一构建出完整的对象。
     */
    public static class Builder {
        // 持有一个 MappedStatement 对象，用于后续设置属性并构建最终对象
        private final MappedStatement mappedStatement = new MappedStatement();

        /**
         * 构造函数，初始化 MappedStatement 对象的基本属性。
         *
         * @param configuration MyBatis 的配置对象
         * @param id SQL 语句的唯一标识
         * @param sqlCommandType SQL 语句的类型
         * @param sqlSource SQL Source
         */
        public Builder(Configuration configuration, String id, SqlCommandType sqlCommandType,
                       SqlSource sqlSource,
                       Class<?> resultType) {
            // 设置 MappedStatement 对象的配置信息
            mappedStatement.configuration = configuration;
            // 设置 MappedStatement 对象的 SQL 语句唯一标识
            mappedStatement.id = id;
            // 设置 MappedStatement 对象的 SQL 语句类型
            mappedStatement.sqlCommandType = sqlCommandType;
            // 设置 MappedStatement 对象的 SQL 语句绑定信息
            mappedStatement.sqlSource = sqlSource;
            mappedStatement.resultType = resultType;
        }

        /**
         * 构建 MappedStatement 对象。
         * 在构建前会断言 SQL 语句的唯一标识和配置对象不为空，确保对象的完整性。
         *
         * @return 构建好的 MappedStatement 对象
         */
        public MappedStatement build() {
            // 断言配置对象不为空
            assert mappedStatement.configuration != null;
            // 断言 SQL 语句的唯一标识不为空
            assert mappedStatement.id != null;
            return mappedStatement;
        }
    }

    /**
     * 获取 SQL 语句的唯一标识
     *
     * @return SQL 语句的唯一标识
     */
    public String getId() {
        return id;
    }

    /**
     * 获取 SQL 语句的类型
     *
     * @return SQL 语句的类型
     */
    public SqlCommandType getSqlCommandType() {
        return sqlCommandType;
    }

    public SqlSource getSqlSource() {
        return sqlSource;
    }

    public Class<?> getResultType() {
        return resultType;
    }
}
